home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NOVA - For the NeXT Workstation
/
NOVA - For the NeXT Workstation.iso
/
Apps
/
ScreenSavers
/
darken
/
VidLev.c
< prev
Wrap
C/C++ Source or Header
|
1992-12-20
|
12KB
|
546 lines
/*
* VidLev.c - get/set display's video level
*/
/*
* Copyright 1991 Purdue Research Foundation, West Lafayette, Indiana
* 47907. All rights reserved.
*
* Written by Vic Abell, Purdue University Computing Center.
*
* This software is not subject to any license of the American Telephone
* and Telegraph Company or the Regents of the University of California.
*
* Permission is granted to anyone to use this software for any purpose on
* any computer system, and to alter it and redistribute it freely, subject
* to the following restrictions:
*
* 1. Neither the author nor Purdue University are responsible for any
* consequences of the use of this software.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Credit to the author and Purdue
* University must appear in documentation and sources.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 4. This notice may not be removed or altered.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright 1991 Purdue Research Foundation.\nAll rights reserved.\n";
#endif
/*
* Usage:
*
* VidLev [-b|-h|-r{a|e|r}|-s{a|e|r}] [-t] [-p path] [value(s)]
*
* where:
*
* -b Blank and repeatedly reblank the screen until stopped.
* If stopped with a SIGHUP, the pre-blanking EVS and
* NVRAM brightness values are restored. The process
* ID is written to a file at the path specified with
* the -p option (default = BIN/VidLev.pid).
*
* The value parameters specify the initial and subsequent
* reblanking intervals in seconds (defaults = 45 and 600).
*
* NOTE: requires root (or NOBODY) permission.
*
* -h Display help.
*
* -p path Specify the path to the file to which the process ID
* is written. This option is only legitimate if the
* the -b option is specified. The default process ID
* file path is BIN/VidLev.pid.
*
* -ra Report EVS and NVRAM brightness values to STDOUT.
* This is the default action for a root (or NOBODY)
* caller.
* -re Report the event driver (EVS) brightness to STDOUT.
* This is the default action for a non-root caller.
* -rr Report the NVRAM brightness to STDOUT.
*
* -sa Set EVS and NVRAM brightness values.
* -se Set the event driver (EVS) brightness.
* -sr set the NVRAM brightness.
*
* -t Set terse reporting -- no titles.
*
* value This optional parameter specifies:
*
* -b reblanking intervale in seconds
* -s[a|e|r] brightness value:
* 0 or dim darkest
* 61 or bright brightest
* 1 - 59 relative brightness between
* darkest (0) and brightest (61)
*
* Note: The default action for a root (or NOBODY) caller is "-ra";
* non-root, "-re".
*/
#include <c.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "missing.h"
#include <dev/m68k/evsio.h>
#include <dev/m68k/video.h>
#if !defined(BIN)
#define BIN "/usr/local/etc"
#endif
#define EDEVICE "/dev/evs0"
#define EVS 1
#define IREPEAT 45
#define NVRAM 2
#define PIDDIGITS 6
#define REPEAT 600
#define VIDLEVPID "/VidLev.pid"
#define VDEVICE "/dev/vid0"
extern int errno;
extern char *sys_errlist[];
extern char *optarg;
extern int optind;
int Efd = -1; /* EVS file descriptor */
int Evsval; /* original EVS value */
struct nvram_info Nvram; /* NVRAM information */
int Pfd = -1; /* PID file descriptor */
char *Pidpath = BIN VIDLEVPID; /* PID file path */
char *Pn; /* program name */
int Vfd = -1; /* video (NVRAM) file descriptor */
void setevs(), setnvram(), sighup();
main(argc, argv)
int argc;
char *argv[];
{
int c; /* character buffer */
int err = 0; /* argument error count */
unsigned int ireblank = IREPEAT;
/* initial reblank interval */
int mblank = 0; /* blank mode */
int mhelp = 0; /* help mode */
int mread = 0; /* read mode */
int mset = 0; /* set mode */
int mterse = 0; /* terse mode */
int mtype = EVS; /* mode type */
char pid[PIDDIGITS+2]; /* process ID */
unsigned int reblank = REPEAT; /* reblanking interval */
unsigned int sleeptm; /* sleep time */
uid_t uid; /* user ID */
int val = -1; /* value paramter */
/*
* Save program name.
*/
if ((Pn = strrchr(argv[0], '/')) != NULL)
Pn++;
else
Pn = argv[0];
/*
* Process arguments.
*/
while ((c = getopt(argc, argv, "bhp:r:s:t")) != EOF) {
switch (c) {
case 'b':
mblank = 1;
break;
case 'h':
mhelp = 1;
break;
case 'p':
Pidpath = optarg;
break;
case 'r':
case 's':
if (c == 'r')
mread = 1;
else
mset = 1;
switch (*optarg) {
case 'a':
mtype = EVS | NVRAM;
break;
case 'e':
mtype = EVS;
break;
case 'r':
mtype = NVRAM;
break;
default:
(void) fprintf(stderr,
"%s: illegal -r/-s option (%c)\n",
Pn, *optarg);
err++;
}
break;
case 't':
mterse = 1;
break;
case '?':
err++;
break;
default:
(void) fprintf(stderr, "%s: unknown option (%c)\n",
Pn, c);
err++;
}
}
/*
* Process value argument.
*/
if (optind <= (argc - 1)) {
if (mblank) {
ireblank = atoi(argv[optind++]);
if (optind <= (argc - 1))
reblank = atoi(argv[optind++]);
else {
(void) fprintf(stderr,
"%s: no reblank interval specified\n",
Pn);
err++;
}
val = BRIGHT_MIN;
} else if (mset) {
if (strcmp(argv[optind], "dim") == 0) {
val = BRIGHT_MIN;
optind++;
} else if (strcmp(argv[optind], "bright") == 0) {
val = BRIGHT_MAX;
optind++;
} else {
val = atoi(argv[optind]);
optind++;
}
}
}
if (optind < argc) {
(void) fprintf(stderr, "%s: extra (unknown) options\n", Pn);
err++;
}
/*
* Check for sensible arguments. Set the default if no modes specified.
*/
uid = getuid();
if ((c = mblank + mset + mread + mhelp) == 0) {
mread = 1;
#if defined(NOBODY)
mtype = (uid == 0 || uid == NOBODY) ? (EVS | NVRAM) : EVS;
#else
mtype = getuid() ? EVS : (EVS | NVRAM);
#endif
} else if (c != 1) {
(void) fprintf(stderr, "%s: use only one of -b, -h, -r, -s\n",
Pn);
err++;
}
#if defined(NOBODY)
if (mblank && uid != 0 && uid != NOBODY)
#else
if (mblank && getuid() != 0)
#endif
{
#if defined(NOBODY)
(void) fprintf(stderr, "%s: must be UID 0 or %d to use -b\n",
Pn, NOBODY);
#else
(void) fprintf(stderr, "%s: must be root to use -b\n", Pn);
#endif
err++;
}
#if defined(NOBODY)
if (((mread || mset) && (mtype & NVRAM)) && uid != 0 && uid != NOBODY)
#else
if (((mread || mset) && (mtype & NVRAM)) && getuid() != 0)
#endif
{
(void) fprintf(stderr,
#if defined(NOBODY)
"%s: must be UID 0 or %d to read or set NVRAM\n",
Pn, NOBODY);
#else
"%s: must be root to read or set NVRAM\n", Pn);
#endif
err++;
}
/*
* Display help and exit if help requested or if errors detected.
*/
if (err || mhelp) {
(void) fprintf(stderr,
"%s usage: [-b|-h|-r{a|e|r}|-s{a|e|r}] [-t] [-p path]", Pn);
(void) fprintf(stderr, " [value(s)]\n");
(void) fprintf(stderr,
#if defined(NOBODY)
" -b blank mode (must be UID 0 or %d)\n", NOBODY);
#else
" -b blank mode (must be root)\n");
#endif
(void) fprintf(stderr,
" value1 = initial repeat seconds (default = %d)\n",
IREPEAT);
(void) fprintf(stderr,
" value2 = subsequent repeat seconds (default = %d)\n",
REPEAT);
(void) fprintf(stderr,
" -h display help\n");
(void) fprintf(stderr,
" -p path specify PID file path, default = %s\n",
BIN VIDLEVPID);
(void) fprintf(stderr,
" -ra report EVS and NVRAM brightnesses to STDOUT\n");
(void) fprintf(stderr,
#if defined(NOBODY)
" (must be UID 0 or %d) (their default action)\n",
NOBODY);
#else
" (must be root) (root default action)\n");
#endif
(void) fprintf(stderr,
" -re report EVS brightness to STDOUT");
(void) fprintf(stderr,
" (non-root default action)\n");
(void) fprintf(stderr,
#if defined(NOBODY)
" -rr report NVRAM brightness to STDOUT (must be UID 0 or %d)\n", NOBODY);
#else
" -rr report NVRAM brightness to STDOUT (must be root)\n");
#endif
(void) fprintf(stderr,
" -sa set EVS and NVRAM brightnesses from value");
(void) fprintf(stderr,
#if defined(NOBODY)
" (must be UID 0 or %d)\n", NOBODY);
#else
" (must be root)\n");
#endif
(void) fprintf(stderr,
" -se set EVS brightness from value\n");
(void) fprintf(stderr,
#if defined(NOBODY)
" -sr set NVRAM brightness from value (must be UID 0 or %d)\n", NOBODY);
#else
" -sr set NVRAM brightness from value (must be root)\n");
#endif
(void) fprintf(stderr,
" -t terse output\n");
(void) fprintf(stderr,
" value optional value(s) for -b and -s[a|e|r]\n");
if (err)
exit(1);
exit(0);
}
/*
* Open EVS device.
*/
if (mblank || ((mset || mread) && (mtype & EVS))) {
if ((Efd = open(EDEVICE, O_RDWR, 0)) == CERROR) {
(void) fprintf(stderr, "%s: can't open %s: %s\n",
Pn, EDEVICE, sys_errlist[errno]);
exit(1);
}
}
/*
* Open video (NVRAM) device.
*/
if (mblank || ((mset || mread) && (mtype & NVRAM))) {
if ((Vfd = open(VDEVICE, O_RDWR, 0)) == CERROR) {
(void) fprintf(stderr, "%s: can't open %s: %s\n",
Pn, VDEVICE, sys_errlist[errno]);
close_exit(1);
}
}
/*
* Read current values.
*/
if (mblank || mread) {
if (mblank || (mtype & EVS)) {
if (ioctl(Efd, EVSIOCB, &Evsval) == CERROR) {
(void) fprintf(stderr,
"%s: can't EVSIOCB %s: $s\n",
Pn, EDEVICE, sys_errlist[errno]);
close_exit(1);
}
}
if (mblank || (mtype & NVRAM)) {
if (ioctl(Vfd, DKIOCGNVRAM, &Nvram) == CERROR) {
(void) fprintf(stderr,
"%s: can't DKIOCGNVRAM %s: $s\n",
Pn, VDEVICE, sys_errlist[errno]);
close_exit(1);
}
}
}
/*
* Print values.
*/
if (mread) {
if (mtype & EVS) {
if (mterse)
(void) printf("%d\n", Evsval);
else
(void) printf("%s: EVS brightness = %d\n",
Pn, Evsval);
}
if (mtype & NVRAM) {
if (mterse)
(void) printf("%d\n", Nvram.ni_brightness);
else
(void) printf("%s: NVRAM brightness = %d\n",
Pn, Nvram.ni_brightness);
}
close_exit(0);
}
/*
* Set new values.
*/
if (mset) {
if (mtype & EVS)
setevs(val);
if (mtype & NVRAM)
(void) setnvram(val);
close_exit(0);
}
/*
* Perform blank function:
*
* 1. Isolate from parent process.
* 2. Record process ID in Pidpath[].
* 3. Enable SIGHUP interrupt.
* 4. Reduce NVRAM brightness to BRIGHT_MIN.
* 5. Repeat step 2 every reblank seconds, because loginwindow
* changes the brightness 30 minutes after logout.
*/
if (mblank) {
if (fork())
close_exit(0);
if ((Pfd = open(Pidpath, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) {
(void) printf("%s: can't open %s: %s\n",
Pn, Pidpath, sys_errlist[errno]);
close_exit(1);
}
(void) sprintf(pid, "%*d\n", PIDDIGITS, getpid());
(void) write(Pfd, pid, strlen(pid));
(void) close(Pfd);
Pfd = -1;
(void) signal(SIGHUP, sighup);
for (sleeptm = ireblank;; sleeptm = reblank) {
(void) setnvram(val);
(void) sleep(sleeptm);
}
/* NOTREACHED */
}
(void) fprintf(stderr, "%s: no action to perform\n", Pn);
exit(1);
}
/*
* close_exit(v) - close all files and exit(v)
*/
close_exit(v)
{
if (Efd >= 0) {
(void) close(Efd);
Efd = -1;
}
if (Pfd >= 0) {
(void) close(Pfd);
Pfd = -1;
}
if (Vfd >= 0) {
(void) close(Vfd);
Vfd = -1;
}
exit(v);
}
/*
* setevs(val) set EVS brightness to val
*/
void
setevs(val)
int val;
{
if (ioctl(Efd, EVSIOSB, &val) == CERROR) {
(void) fprintf(stderr, "%s: can't EVSIOSB %s: $s\n",
Pn, EDEVICE, sys_errlist[errno]);
close_exit(1);
}
}
/*
* setnvram(val) - set NVRAM brightness to val
*/
void
setnvram(val)
int val;
{
if (ioctl(Vfd, DKIOCBRIGHT, &val) == CERROR) {
(void) fprintf(stderr, "%s: can't DKIOCBRIGHT %s: %s",
Pn, VDEVICE, sys_errlist[errno]);
close_exit(1);
}
}
/*
* sighup() - process SIGHUP
*/
void
sighup()
{
int val;
(void) setevs(Evsval);
val = Nvram.ni_brightness;
(void) setnvram(val);
(void) unlink(Pidpath);
close_exit(0);
}